/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package privileges.business;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import login.bean.LoginBean;
import privileges.dao.UserDAO;

/**
 *
 * @author JuanFelipe
 */
public class UserBusiness {
    
    public Connection conn;
    private LoginBean lb ;

    public UserBusiness() {
        lb = (LoginBean) FacesContext.getCurrentInstance()
                   .getExternalContext().getSessionMap().get("loginBean");
        this.conn = lb.getCurrentConnection();
    }
    

    public UserBusiness(Connection conn) {
        this.conn = conn;
    }
    
    public List<User> getUsers() {
        String sql = "select user,host,password,Grant_priv from mysql.user";
        List<User> users = new ArrayList<>();
        try {
            ResultSet rs = new UserDAO(conn).executeStatement(sql);
            while (rs.next()) {
                ArrayList<String> stringList = new ArrayList<String>();
                for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                    stringList.add(rs.getString(i));
                }
                users.add(new User(stringList.get(0), stringList.get(1),
                        stringList.get(2), stringList.get(3)));
            }
            return users;
        } catch (Exception e) {
            return users;
        }
    }

    public void dropUser(String name,String host) throws SQLException {
        new UserDAO(conn).dropUser(name,host);
    }
    
    public String constructSchemaPrivileges(List<String> selectedStructureOptions, List<String> selectedDataOptions, List<String> selectedAdministrationOptions) {
        if (!(selectedStructureOptions == null && selectedDataOptions == null
                && selectedAdministrationOptions == null)) {
            StringBuilder sentenciaSB = new StringBuilder("");
            if (!(selectedAdministrationOptions == null)) {
                for (String selected : selectedAdministrationOptions) {
                    sentenciaSB.append(selected);
                    sentenciaSB.append(",");
                }
            }
            if (!(selectedStructureOptions == null)) {
                for (String selected : selectedStructureOptions) {
                    sentenciaSB.append(selected);
                    sentenciaSB.append(",");
                }
            }
            if (!(selectedDataOptions == null)) {
                for (String selected : selectedDataOptions) {
                    sentenciaSB.append(selected);
                    sentenciaSB.append(",");
                }
            }

            if(sentenciaSB.length()>0)
                sentenciaSB.deleteCharAt(sentenciaSB.length() - 1);
            return sentenciaSB.toString();
        } else {
            return "";
        }

    }
    public void createUser(String name, String host, String password, List<String> selectedStructureOptions, List<String> selectedDataOptions, List<String> selectedAdministrationOptions, String maxUserConnections, String maxConnectionsPerHour, String maxUpdatesPerHour, String maxQueriesPerHour
    ) throws SQLException {

        if (!(selectedStructureOptions == null && selectedDataOptions == null
                && selectedAdministrationOptions == null)) {
            if (!(selectedAdministrationOptions.isEmpty() && selectedDataOptions.isEmpty() && selectedStructureOptions.isEmpty())) {
                StringBuilder sentenciaSB = new StringBuilder("GRANT  ");
                if (!(selectedAdministrationOptions == null)) {
                    if (!selectedAdministrationOptions.isEmpty()) {
                        for (String selected : selectedAdministrationOptions) {
                            sentenciaSB.append(selected);
                            sentenciaSB.append(",");
                        }
                    }
                }
                if (!(selectedStructureOptions == null)) {
                    if (!selectedStructureOptions.isEmpty()) {
                        for (String selected : selectedStructureOptions) {
                            sentenciaSB.append(selected);
                            sentenciaSB.append(",");
                        }
                    }
                }
                if (!(selectedDataOptions == null)) {
                    if (!selectedDataOptions.isEmpty()) {
                        for (String selected : selectedDataOptions) {
                            sentenciaSB.append(selected);
                            sentenciaSB.append(",");
                        }
                    }
                }
                if (sentenciaSB.length() > 0) {
                    sentenciaSB.deleteCharAt(sentenciaSB.length() - 1);
                }
                String nU = " ON *.* TO '" + name + "'@'" + host + "' IDENTIFIED BY '"
                        + password + "' WITH MAX_QUERIES_PER_HOUR "
                        + maxQueriesPerHour + " MAX_UPDATES_PER_HOUR "
                        + maxUpdatesPerHour + " MAX_CONNECTIONS_PER_HOUR "
                        + maxConnectionsPerHour + " MAX_USER_CONNECTIONS "
                        + maxUserConnections + ";";
                sentenciaSB.append(nU);
                new UserDAO(conn).executeStatementUpdate(sentenciaSB.toString());
            }

        } else {
            new UserDAO(conn).createUser(name, host, password);
        }
    }
    
    private boolean isGrantOption(String privileges){
        StringTokenizer st = new StringTokenizer(privileges, "\\,");
        while(st.hasMoreTokens())
            if(st.nextToken().equals("GRANT"))
                return true;
        return false;
    
    }
    public void doPrivilegesSchemaExist(SchemaPrivilege sp
            ,String name,String host) throws SQLException{
            doErasePrivileges(sp.getSchemaName(),"*", name, host);
            StringBuilder sb = new StringBuilder("GRANT ");
            sb.append(removeGrant(sp.getSchemaPrivileges()));
            String nU;
            if(isGrantOption(sp.getSchemaPrivileges()))
                nU = " ON "+sp.getSchemaName()+".* TO '" + name + "'@'" + host + "' WITH GRANT OPTION;";
            else
                nU = " ON "+sp.getSchemaName()+".* TO '" + name + "'@'" + host + "';";            
            sb.append(nU);
            new UserDAO(conn).executeStatementUpdate(sb.toString());       
    }
    private String removeGrant(String privileges) {
        StringTokenizer st = new StringTokenizer(privileges, "\\,");
        StringBuilder sb = new StringBuilder();
        String v;
        while (st.hasMoreTokens()) {
            v = st.nextToken();
            if (v.equals("GRANT")) {
            } else {
                sb.append(v);
                sb.append(",");
            }
        }
        if(sb.length() > 0)
            sb.deleteCharAt(sb.length() - 1).toString();
        return sb.toString();

    }
    public void doPrivilegesSchema(SchemaPrivilege sp
            ,String name,String host) throws SQLException{
            StringBuilder sb = new StringBuilder("GRANT ");
            sb.append(removeGrant(sp.getSchemaPrivileges()));
            String nU;
            if(isGrantOption(sp.getSchemaPrivileges()))
                nU = " ON "+sp.getSchemaName()+".* TO '" + name + "'@'" + host + "' WITH GRANT OPTION;";
            else
                nU = " ON "+sp.getSchemaName()+".* TO '" + name + "'@'" + host + "';";
            sb.append(nU);
            new UserDAO(conn).executeStatementUpdate(sb.toString());     
    }
    public String doErasePrivileges(String schema,String table,String user,String host){
        try {
            new UserDAO(conn).executeStatementUpdate("REVOKE ALL PRIVILEGES ON "+schema+"."+table+" FROM '" + user + "'@'" + host + "';");
            new UserDAO(conn).executeStatementUpdate("REVOKE GRANT OPTION ON "+schema+"."+table+" FROM '" + user + "'@'" + host + "';");
            new UserDAO(conn).executeStatementUpdate("GRANT USAGE ON "+schema+"."+table+" TO '" + user + "'@'" + host + "' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;");
            return "ok";
        } catch (SQLException ex) {
            return ex.getLocalizedMessage();
        }
        
    }
    public void addAllPrivileges(String schema,String name,String host) throws SQLException{
        new UserDAO(conn).executeStatementUpdate("GRANT ALL PRIVILEGES ON "+schema+".* TO '" + name + "'@'" + host + "' WITH GRANT OPTION;");
    }
    
    public List<SchemaPrivilege> getSchemaPrivilegesUser(String userName,String host) throws SQLException {
        ResultSet resultSet = new UserDAO(conn).executeStatement("SELECT * FROM  mysql.db WHERE USER =  '" + userName + "' && HOST = '"+host+"';");
        List<SchemaPrivilege> sps = new ArrayList<>();
        while (resultSet.next()) {
            int i = 4;
            SchemaPrivilege sp = new SchemaPrivilege();
            sp.setSchemaName(resultSet.getString(2));
            StringBuilder response = new StringBuilder();
            for (i = 4; i <= resultSet.getMetaData().getColumnCount(); i++) {
                if(!(resultSet.getMetaData().getColumnName(i).equals("Create_tmp_table_priv"))) {
                    if (resultSet.getString(i).equals("Y")) {
                        StringTokenizer st = new StringTokenizer(resultSet.getMetaData().getColumnName(i), "\\_");
                        if (st.countTokens() > 2) {
                            while (st.hasMoreTokens()) {
                                response.append(st.nextToken().toUpperCase());
                                response.append(" ");
                            }
                            response.delete(response.length() - 6, response.length());
                        } else {
                            response.append(st.nextToken().toUpperCase());
                        }
                        response.append(",");
                    } else {
                        response.append("");
                    }
                } else {
                    if(resultSet.getString(i).equals("Y"))
                        response.append("CREATE TEMPORARY TABLES,");
                    else
                        response.append("");
                }
            }
            if (response.length() > 0) {
                response.deleteCharAt(response.length() - 1);
            }
            sp.setSchemaPrivileges(response.toString());
            sps.add(sp);
        }
        return sps;
    }

    public List<String> getSeStruOp(String priv) {
        System.out.println("entro user buss strucOption "+priv);
        StringTokenizer st = new StringTokenizer(priv, "//,");
        List<String> reStru = new ArrayList<>();
        while (st.hasMoreTokens()) {
            String value = st.nextToken();
            if (value.toUpperCase().equals("DROP")) {
                reStru.add("DROP");
            }
            if (value.toUpperCase().equals("INDEX")) {
                reStru.add("INDEX");
            }
            if (value.toUpperCase().equals("ALTER")) {
                reStru.add("ALTER");
            }
            if (value.toUpperCase().equals("CREATE TEMPORARY TABLES")) {
                reStru.add("CREATE TEMPORARY TABLES");
            }
            if (value.toUpperCase().equals("CREATE VIEW")) {
                reStru.add("CREATE VIEW");
            }
            if (value.toUpperCase().equals("SHOW VIEW")) {
                reStru.add("SHOW VIEW");
            }
            if (value.toUpperCase().equals("CREATE ROUTINE")) {
                reStru.add("CREATE ROUTINE");
            }
            if (value.toUpperCase().equals("ALTER ROUTINE")) {
                reStru.add("ALTER ROUTINE");
            }
            if (value.toUpperCase().equals("EXECUTE")) {
                reStru.add("EXECUTE");
            }
            if (value.toUpperCase().equals("EVENT")) {
                reStru.add("EVENT");
            }
            if (value.toUpperCase().equals("TRIGGER")) {
                reStru.add("TRIGGER");
            }
            if (value.toUpperCase().equals("CREATE")) {
                reStru.add("CREATE");
            }
        }
        return reStru;
    }

    public List<String> getDaOp(String pri) {
        System.out.println("entro user buss dataOption "+pri);
        StringTokenizer st = new StringTokenizer(pri, "//,");
        List<String> reStru = new ArrayList<>();
        while (st.hasMoreTokens()) {
            String value = st.nextToken();
            if (value.toUpperCase().equals("SELECT")) {
                reStru.add("SELECT");
            }
            if (value.toUpperCase().equals("INSERT")) {
                reStru.add("INSERT");
            }
            if (value.toUpperCase().equals("UPDATE")) {
                reStru.add("UPDATE");
            }
            if (value.toUpperCase().equals("DELETE")) {
                reStru.add("DELETE");
            }
            if (value.toUpperCase().equals("FILE")) {
                reStru.add("FILE");
            }
        }
        return reStru;
    }

    public List<String> getAdOp(String priv) {
        System.out.println("entro user buss adminOption "+priv);
        StringTokenizer st = new StringTokenizer(priv, "//,");
        List<String> reStru = new ArrayList<>();
        while (st.hasMoreTokens()) {
            String value = st.nextToken();
            if (value.toUpperCase().equals("GRANT")) {
                reStru.add("GRANT OPTION");
            }
            if (value.toUpperCase().equals("REFERENCES")) {
                reStru.add("REFERENCES");
            }
            if (value.toUpperCase().equals("LOCK TABLES")) {
                reStru.add("LOCK TABLES");
            }
            if (value.toUpperCase().equals("SUPER")) {
                reStru.add("SUPER");
            }
            if (value.toUpperCase().equals("PROCESS")) {
                reStru.add("PROCESS");
            }
            if (value.toUpperCase().equals("RELOAD")) {
                reStru.add("RELOAD");
            }
            if (value.toUpperCase().equals("SHUTDOWN")) {
                reStru.add("SHUTDOWN");
            }
            if (value.toUpperCase().equals("SHOW DATABASES")) {
                reStru.add("SHOW DATABASES");
            }
            if (value.toUpperCase().equals("REPLICATION CLIENT")) {
                reStru.add("REPLICATION CLIENT");
            }
            if (value.toUpperCase().equals("REPLICATION SLAVE")) {
                reStru.add("REPLICATION SLAVE");
            }
            if (value.toUpperCase().equals("CREATE USER")) {
                reStru.add("CREATE USER");
            }
        }
        return reStru;
    }

    public String changePassword(String user,String actualUser, String host,String actualHost, String password) {
        try {
            if(!(user.equals(actualUser) && host.equals(actualHost)))
                new UserDAO(conn).changeUserHost(user,actualUser,host,actualHost);
            changePass(user, host, password);
            return "Los datos de "+user+" han sido actualizados";
        } catch (SQLException ex) {
            return ex.getLocalizedMessage();
        }
    }
    public void changePass(String user,String host,String password){
        try {
            new UserDAO(conn).changePassword(user,host,password);
        } catch (SQLException ex) {
        }
    }

    public String getUserGlobalPrivileges(String user, String host) throws SQLException {
        ResultSet resultSet = new UserDAO(conn).executeStatement("SELECT * FROM  mysql.user WHERE USER =  '" + user + "' && HOST = '"+host+"';");
        StringBuilder globalPrivileges = new StringBuilder();
        while (resultSet.next()) {
            int i = 4;
            for (i = 4; i <= resultSet.getMetaData().getColumnCount(); i++) {
                if(!(resultSet.getMetaData().getColumnName(i).equals("Create_tmp_table_priv")) 
                        && !(resultSet.getMetaData().getColumnName(i).equals("Show_db_priv")) 
                        && !(resultSet.getMetaData().getColumnName(i).equals("Repl_client_priv"))
                        && !(resultSet.getMetaData().getColumnName(i).equals("Repl_slave_priv"))) {
                    if (resultSet.getString(i).equals("Y")) {
                        StringTokenizer st = new StringTokenizer(resultSet.getMetaData().getColumnName(i), "\\_");
                        if (st.countTokens() > 2) {
                            while (st.hasMoreTokens()) {
                                globalPrivileges.append(st.nextToken().toUpperCase());
                                globalPrivileges.append(" ");
                            }
                            globalPrivileges.delete(globalPrivileges.length() - 6, globalPrivileges.length());
                        } else {
                            globalPrivileges.append(st.nextToken().toUpperCase());
                        }
                        globalPrivileges.append(",");
                    } else {
                        globalPrivileges.append("");
                    }
                } else {
                    if(resultSet.getString(i).equals("Y") 
                            && resultSet.getMetaData().getColumnName(i).equals("Create_tmp_table_priv"))
                        globalPrivileges.append("CREATE TEMPORARY TABLES,");
                    if(resultSet.getString(i).equals("Y") 
                            && resultSet.getMetaData().getColumnName(i).equals("Show_db_priv"))
                        globalPrivileges.append("SHOW DATABASES,");
                    if(resultSet.getString(i).equals("Y") 
                            && resultSet.getMetaData().getColumnName(i).equals("Repl_client_priv"))
                        globalPrivileges.append("REPLICATION CLIENT,");
                    if(resultSet.getString(i).equals("Y") 
                            && resultSet.getMetaData().getColumnName(i).equals("Repl_slave_priv"))
                        globalPrivileges.append("REPLICATION SLAVE,");           
                }
            }
            if (globalPrivileges.length() > 0) {
                globalPrivileges.deleteCharAt(globalPrivileges.length() - 1);
            }

        }
        System.out.println(globalPrivileges.toString());
        return globalPrivileges.toString();      
    }

    public void doGlobalPrivileges(String user, String host
            , List<String> selectedAdminOptions, List<String> selectedDataOptions
            , List<String> selectedStructOptions,String maxConnPH
            , String maxQuePH,String maxUpdPH,String maxUsConn) throws SQLException {
        String message = doErasePrivileges("*","*", user, host);
        System.out.println("message " + message);
        StringBuilder sb = new StringBuilder();
        sb.append("GRANT ");
        for(String option: selectedAdminOptions){
            if(!option.equals("")){
                sb.append(option);
                sb.append(","); 
            }
        } 
        for(String option: selectedStructOptions){
            if(!option.equals("")){
                sb.append(option);
                sb.append(",");
            }
        }
        for(String option: selectedDataOptions){
            if(!option.equals("")){
                sb.append(option);
                sb.append(",");
            }
        }
        if(sb.length() > 0)
            sb.deleteCharAt(sb.length()-1);
        String nU = " ON *.* TO '" + user + "'@'" + host 
                + "' WITH MAX_QUERIES_PER_HOUR "+maxQuePH
                +" MAX_CONNECTIONS_PER_HOUR "+maxConnPH
                +" MAX_UPDATES_PER_HOUR "
                +maxUpdPH+" MAX_USER_CONNECTIONS "
                +maxUsConn+";";
        sb.append(nU);
        System.out.println(sb.toString());
        new UserDAO(conn).executeStatementUpdate(sb.toString());
    }

    public List<String> getMaxGO(String user, String host) throws SQLException {
        ResultSet resultSet = new UserDAO(conn).executeStatement("SELECT max_connections,max_questions ,max_updates,max_user_connections FROM  mysql.user WHERE USER =  '" + user + "' && HOST = '"+host+"';");
        List<String> go = new ArrayList<>();
        
        while(resultSet.next()){
            go.add(resultSet.getString(1));
            go.add(resultSet.getString(2));
            go.add(resultSet.getString(3));
            go.add(resultSet.getString(4));  
        }      
        System.out.println("grant options "+go.toString());
        return go;
     }

    public List<String> getTablesFromDb(String selectedSchema) throws SQLException {
        ResultSet  rs = new UserDAO(conn).getTablesFromDB(selectedSchema);
        List<String> tables = new ArrayList<>();
        while(rs.next()){      
            System.out.println("tables "+ rs.getString(1));
            tables.add(rs.getString(1));
        }
        return tables;
    }

    public List<String> getColumnNames(String selectedSchema, String selectedTable) throws SQLException {
        ResultSet rs = new UserDAO(conn)
                .executeStatement("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='"+selectedSchema+"' AND TABLE_NAME='"+selectedTable+"';");
        List<String> columns = new ArrayList<>();
        while(rs.next()){
            columns.add(rs.getString(1));
        }
        System.out.println("columns "+ columns.toString());
        return columns;
    }

    public List<String> getPrivilegesOnTable(String user, String host, String selectedSchema, String selectedTable) throws SQLException {
        ResultSet rs = new UserDAO(conn)
                .executeStatement("SELECT Table_priv FROM mysql.tables_priv WHERE host='"
                        +host+"' AND user='"
                        +user+"' AND Db='"
                        +selectedSchema+"' AND Table_name = '"
                        +selectedTable+"';");
        List<String> tablePriv = new ArrayList<>();
        while(rs.next()){
            StringTokenizer st = new StringTokenizer(rs.getString(1), "\\,");
            while(st.hasMoreTokens()){
                tablePriv.add(st.nextToken().toUpperCase());
            }
        }
        System.out.println("Tables privileges "+tablePriv.toString());
        return tablePriv;
    }

    public List<List<String> > getColumnsSelect(String user, String host, String selectedSchema, String selectedTable) throws SQLException {
        ResultSet rs = new UserDAO(conn).executeStatement("SELECT Column_name,Column_priv FROM mysql.columns_priv WHERE "
                + "host='"+host
                +"' AND user='"+user
                +"' AND DB='"+selectedSchema
                +"' AND Table_name='"+selectedTable+"';");
            List<List<String> > listaDeLista = new ArrayList< >();
            List<String> sbSelect = new ArrayList<>();
            List<String> sbInsert = new ArrayList<>();
            List<String> sbUpdate = new ArrayList<>();
            List<String> sbReferences = new ArrayList<>();
            while(rs.next()){
                StringTokenizer st = new StringTokenizer(rs.getString(2),"\\,");
                while(st.hasMoreTokens()){
                    String token = st.nextToken();
                    if(token.equals("Select")){
                        sbSelect.add(rs.getString(1));
                    }
                    if(token.equals("Insert")){
                        sbInsert.add(rs.getString(1));
                    }
                    if(token.equals("Update")){
                        sbUpdate.add(rs.getString(1));
                    }
                    if(token.equals("References")){
                        sbReferences.add(rs.getString(1));
                    }
                }

            }
            listaDeLista.add(sbSelect);
            listaDeLista.add(sbInsert);
            listaDeLista.add(sbUpdate);
            listaDeLista.add(sbReferences);
            
            return listaDeLista;
        
    }

    public String setPrivilegesOnTable(String user, String host
            , String selectedSchema, String selectedTable
            , List<String> selectedOptionsTables, List<String> selectedOptionsSelect
            , List<String> selectedOptionsInsert, List<String> selectedOptionsUpdate
            , List<String> selectedOptionsReferences) {
        doErasePrivileges(selectedSchema, selectedTable, user, host);
        boolean colon = false;
        boolean existGrant = false;
        if (!selectedOptionsTables.isEmpty()) {
            try {
                //Se forma el String de los permisos que son para tablas
                StringBuilder sb = new StringBuilder("GRANT ");
                for (String oT : selectedOptionsTables) {
                    if (!(oT.equals("GRANT"))) {
                        sb.append(oT);
                        sb.append(",");
                    } else {
                        existGrant = true;
                    }
                }
                colon = true;
                sb = reduceLastCharacter(sb);
                ///////////////////////////////////////////////////////////
                //Se forman las sentencias para los permisos por columnas
                sb.append(setPrivilegesOnColumns(user, host, selectedSchema
                        , selectedTable, selectedOptionsSelect, selectedOptionsInsert
                        , selectedOptionsUpdate, selectedOptionsReferences, existGrant,colon));
                new UserDAO(conn).executeStatementUpdate(sb.toString());
                return "Permisos actualizados correctamente";
            } catch (SQLException ex) {
                ex.printStackTrace();
                return ex.getLocalizedMessage();
            }
        } else {
            if (selectedOptionsSelect.isEmpty() && selectedOptionsInsert.isEmpty()
                    && selectedOptionsUpdate.isEmpty() && selectedOptionsReferences.isEmpty()) {
                return "Todos los privilegios sobre la tabla " + selectedTable.toUpperCase() + " han sido eliminidos";
            } else {
                StringBuilder sb = new StringBuilder("GRANT ");
                sb.append(setPrivilegesOnColumns(user, host, selectedSchema
                        , selectedTable, selectedOptionsSelect, selectedOptionsInsert
                        , selectedOptionsUpdate, selectedOptionsReferences, existGrant,colon));
                try {
                    new UserDAO(conn).executeStatementUpdate(sb.toString());
                    return "Permisos actualizados correctamente";
                } catch (SQLException ex) {
                    ex.printStackTrace();
                    return ex.getLocalizedMessage();
                }
                
            }
        }

    }
    private StringBuilder reduceLastCharacter(StringBuilder st){
        if(st.length() > 0){
            System.out.println("entra");
            System.out.println(st);
            System.out.println("boorrado");
            System.out.println(st.deleteCharAt(st.length()-1));
            return st;
        }
        return st;
    }
    
    private String setPrivilegesOnColumns( String user, String host
            , String selectedSchema, String selectedTable,List<String> selectedOptionsSelect, List<String> selectedOptionsInsert
            , List<String> selectedOptionsUpdate, List<String> selectedOptionsReferences,boolean existGrant,boolean enter) { 
        StringBuilder st;
        if(enter)
            st = new StringBuilder(",");
        else
            st = new StringBuilder("");
        
        if(!selectedOptionsSelect.isEmpty()){
            st.append("Select(");
            for(String optionSelect : selectedOptionsSelect){
                st.append(optionSelect);
                st.append(",");
            }
            st = reduceLastCharacter(st);
            st.append("),");
        }
        if(!selectedOptionsInsert.isEmpty()){
            st.append("Insert(");
            for(String optionSelect : selectedOptionsInsert){
                st.append(optionSelect);
                st.append(",");
            }
            st = reduceLastCharacter(st);
            st.append("),");
        }
        if(!selectedOptionsUpdate.isEmpty()){
            st.append("Update(");
            for(String optionSelect : selectedOptionsUpdate){
                st.append(optionSelect);
                st.append(",");
            }
            st = reduceLastCharacter(st);
            st.append("),");
        }
        if(!selectedOptionsReferences.isEmpty()){
            st.append("References(");
            for(String optionSelect : selectedOptionsReferences){
                st.append(optionSelect);
                st.append(",");
            }
            st = reduceLastCharacter(st);
            st.append("),");
        }
        st = reduceLastCharacter(st);
        if (existGrant) {
            String nU = " ON " + selectedSchema + "." + selectedTable + " TO '" + user + "'@'" + host + "' WITH GRANT OPTION;";
            st.append(nU);
        } else {
            String nU = " ON " + selectedSchema + "." + selectedTable + " TO '" + user + "'@'" + host + "'";
            st.append(nU);
        }
        return st.toString();

    }
}
